package at.ac.univie.zsu.aguataplan.ui;

import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.List;

import javax.swing.JDialog;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;

import at.ac.univie.zsu.aguataplan.domain.DetectedEvent;
import at.ac.univie.zsu.aguataplan.domain.Event;
import at.ac.univie.zsu.aguataplan.domain.EventAttribute;
import at.ac.univie.zsu.aguataplan.domain.EventAttributeValue;
import at.ac.univie.zsu.aguataplan.domain.Video;
import at.ac.univie.zsu.aguataplan.exception.DatabaseException;
import at.ac.univie.zsu.aguataplan.property.GeneralProperties;
import at.ac.univie.zsu.aguataplan.property.I18nProperties;
import at.ac.univie.zsu.aguataplan.property.SystemProperties;
import at.ac.univie.zsu.aguataplan.property.UIProperties;
import at.ac.univie.zsu.aguataplan.service.DetectedEventManager;
import at.ac.univie.zsu.aguataplan.service.EventManager;
import at.ac.univie.zsu.aguataplan.ui.template.IDialogList;
import at.ac.univie.zsu.aguataplan.ui.template.ListPanel;
import at.ac.univie.zsu.aguataplan.util.Constants;
import at.ac.univie.zsu.aguataplan.video.util.IExit;

/**
 * Dialog to admin club
 * 
 * TODO: better exception handling (different messages,...)
 * 
 * @author gerry
 * 
 */
public class DialogVideo extends JDialog implements UIConstants, Constants, IExit, IForegroundChange {

	private static final long serialVersionUID = 1L;

	private JDialog parent;
	private MainWindow mainWindow;
	private GeneralProperties generalProperties;
	private I18nProperties i18nProp;
	private UIProperties uiProp;
	private SystemProperties systemProp;

	private Video video;

	private VideoPlayerPanel videoPlayerPanel;

	private EventManager eventManager;
	private DetectedEventManager detectedEventManager;

	private ListPanel eventPanel;

	private String type;
	private DetectedEvent detectedEvent;

	private Event e;
	private EventAttribute ea;

	// ----------------------------------------------------
	// CONSTRUCTOR
	// ----------------------------------------------------

	public DialogVideo(JDialog parent, MainWindow mainWindow, GeneralProperties generalProperties, Video video) {
		super(parent, true);

		this.parent = parent;
		this.mainWindow = mainWindow;
		this.generalProperties = generalProperties;
		this.i18nProp = generalProperties.getI18nProperties();
		this.uiProp = generalProperties.getUiProperties();
		this.systemProp = generalProperties.getSystemProperties();
		this.video = video;

		this.eventManager = mainWindow.getServices().getEventManager();
		this.detectedEventManager = mainWindow.getServices().getDetectedEventManager();

		this.setLayout(null);

		setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
		addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				exit();
			}
		});
		setLocationByPlatform(true);

		setTitle(i18nProp.getString(VIDEO_HEADER));

		addEntries();
	}

	// ----------------------------------------------------
	// METHODS
	// ----------------------------------------------------

	public void exit() {
		videoPlayerPanel.quit();
	}

	private void addEntries() {

		type = EVENT;
		eventPanel = new ListPanel(this, generalProperties, new IDialogList() {

			@Override
			public List<?> initText() {
				List<?> list = null;
				if (type.equals(EVENT)) {
					try {
						list = eventManager.getEventListNonEmpty();
					} catch (DatabaseException e) {
						JOptionPane.showMessageDialog(DialogVideo.this, i18nProp.getString(EX_EVENT_LIST_DESC),
								i18nProp.getString(EX_EVENT), JOptionPane.ERROR_MESSAGE);
					}
				} else if (type.equals(EVENTATTRIBUTE)) {
					try {
						list = eventManager.getEventAttributeListByEventNonEmpty(e);
					} catch (DatabaseException e) {
						JOptionPane.showMessageDialog(DialogVideo.this, i18nProp.getString(EX_EVENT_LIST_DESC),
								i18nProp.getString(EX_EVENT), JOptionPane.ERROR_MESSAGE);
					}
				} else if (type.equals(EVENTATTRIBUTEVALUE)) {
					try {
						list = eventManager.getEventAttributeValueStringListByEventAttribute(ea);
					} catch (DatabaseException e) {
						JOptionPane.showMessageDialog(DialogVideo.this, i18nProp.getString(EX_EVENT_LIST_DESC),
								i18nProp.getString(EX_EVENT), JOptionPane.ERROR_MESSAGE);
					}
				}
				return list;
			}

			@Override
			public void registerDoubleClick(Object obj) {
				// not initialized
				if (obj == null) {
					type = EVENT;
					eventPanel.reInit(EVENT_BORDER);
				}

				if (type.equals(EVENT)) {
					// pause after event is detected
					if (videoPlayerPanel.isPlaying()) {
						videoPlayerPanel.pause();
					}

					// TODO: allow defined event length
					try {
						detectedEvent = detectedEventManager.addEventToDetectedEvent((Event) obj,
								DialogVideo.this.videoPlayerPanel.getPositionFloat(),
								DialogVideo.this.videoPlayerPanel.getTimeLong(), EVENT_LENGTH, video);
					} catch (DatabaseException e) {
						JOptionPane.showMessageDialog(DialogVideo.this, i18nProp.getString(EX_DETECTEDEVENT_ADD_DESC),
								i18nProp.getString(EX_DETECTEDEVENT), JOptionPane.ERROR_MESSAGE);
					}
					e = (Event) obj;
					type = EVENTATTRIBUTE;
					eventPanel.reInit(i18nProp.getString(EVENT_ATTRIBUTEBORDER));
				} else if (type.equals(EVENTATTRIBUTE)) {
					try {
						detectedEvent = detectedEventManager.addEventAttributeToDetectedEvent(detectedEvent,
								(EventAttribute) obj);
					} catch (DatabaseException e) {
						JOptionPane.showMessageDialog(DialogVideo.this, i18nProp.getString(EX_DETECTEDEVENT_ADD_DESC),
								i18nProp.getString(EX_DETECTEDEVENT), JOptionPane.ERROR_MESSAGE);
					}
					ea = (EventAttribute) obj;
					type = EVENTATTRIBUTEVALUE;
					eventPanel.reInit(i18nProp.getString(EVENT_ATTRIBUTEVALUEBORDER));
				} else if (type.equals(EVENTATTRIBUTEVALUE)) {
					try {
						detectedEvent = detectedEventManager.addEventAttributeValueToDetectedEvent(detectedEvent,
								(EventAttributeValue) obj);
					} catch (DatabaseException e) {
						JOptionPane.showMessageDialog(DialogVideo.this, i18nProp.getString(EX_DETECTEDEVENT_ADD_DESC),
								i18nProp.getString(EX_DETECTEDEVENT), JOptionPane.ERROR_MESSAGE);
						e.printStackTrace();
					}
					type = EVENT;
					eventPanel.reInit(i18nProp.getString(EVENT_BORDER));
				}

			}

			@Override
			public List<?> initCombo() {
				return null;
			}

			@Override
			public List<DetectedEvent> selectDestectedEvent(Object obj) {
				return null;
			}
		});
		// eventPanel.init(i18nProp.getString(EVENT_BORDER), PANEL_SIZE_X_LIST,
		// PANEL_SIZE_Y_LIST);
		eventPanel.init(i18nProp.getString(EVENT_BORDER), PANEL_SIZE_X_LIST, PANEL_SIZE_Y_ENTRY_THIRD, false);

		ListPanel detectedEventPanel = new ListPanel(this, generalProperties, new IDialogList() {

			@Override
			public void registerDoubleClick(Object obj) {
				DetectedEvent detectedEvent = (DetectedEvent) obj;
				videoPlayerPanel.setPositionFloat(detectedEvent.getDetPosition());
			}

			@Override
			public List<?> initText() {
				List<DetectedEvent> list = null;
				try {
					list = detectedEventManager.getDetectedEventByVideoList(video);
				} catch (DatabaseException e) {
					JOptionPane.showMessageDialog(DialogVideo.this, i18nProp.getString(EX_EVENT_LIST_DESC),
							i18nProp.getString(EX_EVENT), JOptionPane.ERROR_MESSAGE);
				}

				return list;
			}

			@Override
			public List<?> initCombo() {
				List<Event> list = null;
				try {
					list = eventManager.getEventListNonEmptyAll();
				} catch (DatabaseException e) {
					JOptionPane.showMessageDialog(DialogVideo.this, i18nProp.getString(EX_EVENT_LIST_DESC),
							i18nProp.getString(EX_EVENT), JOptionPane.ERROR_MESSAGE);
				}
				return list;
			}

			@Override
			public List<DetectedEvent> selectDestectedEvent(Object obj) {
				List<DetectedEvent> list = null;

				try {
					list = detectedEventManager.getDetectedEventByEvent((Event) obj, video);
				} catch (DatabaseException e) {
					JOptionPane.showMessageDialog(DialogVideo.this, i18nProp.getString(EX_EVENT_LIST_DESC),
							i18nProp.getString(EX_EVENT), JOptionPane.ERROR_MESSAGE);
				}
				return list;
			}
		});
		detectedEventPanel.init(i18nProp.getString(DETECTEDEVENT_BORDER), PANEL_SIZE_X_LIST_LARGE, PANEL_SIZE_Y_LARGE,
				true);

		eventPanel.addChild(detectedEventPanel);
		detectedEventPanel.addParent(eventPanel);

		// ---------------

		if (SwingUtilities.isEventDispatchThread()) {
			System.err.println(this.getClass().getCanonicalName() + " running in wrong thread");
			System.exit(-1);
		}

		String s = video.getLocationPath();

		videoPlayerPanel = new VideoPlayerPanel(DialogVideo.this.generalProperties, this, systemProp.getDirVideo()
				+ Sep + s);
		mainWindow.addExit(this);

		// ---------------

		// ---------------

		videoPlayerPanel.setSize(PANEL_VIDEO_X, PANEL_VIDEO_Y);
		videoPlayerPanel.setLocation(SPACING, SPACING);
		this.add(videoPlayerPanel);

		eventPanel.setSize(PANEL_SIZE_X_LIST, PANEL_SIZE_Y_ENTRY_THIRD);
		eventPanel.setLocation(SPACING, PANEL_VIDEO_Y + SPACING);
		// eventPanel.setLocation(PANEL_VIDEO_X+SPACING, SPACING);
		this.add(eventPanel);

		detectedEventPanel.setSize(PANEL_SIZE_X_LIST_LARGE, PANEL_SIZE_Y_LARGE);
		// detectedEventPanel.setLocation(SPACING + PANEL_SIZE_X_LIST + SPACING,
		// PANEL_VIDEO_Y + SPACING);
		detectedEventPanel.setLocation(PANEL_VIDEO_X + SPACING, SPACING);
		this.add(detectedEventPanel);
		this.pack();

		this.setSize(1400, 850);
		// this.setResizable(false);
		this.setResizable(true);

		videoPlayerPanel.init();

	}

	@Override
	public void setInForeground(boolean value) {
		// if (value) {
		this.parent.setVisible(value);
		this.parent.setModal(value);
		this.setVisible(value);
		this.setModal(value);
		// } else {
		// this.setModal(value);
		// this.setVisible(value);
		// this.parent.setModal(value);
		// this.parent.setVisible(value);
		// }

	}
}
